/*
 * @(#)DocumentEmailArchiveManager.java
 *
 * Copyright (c) 2005 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.dms.core;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.mail.BodyPart;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

import com.dcivision.dms.DmsErrorConstant;
import com.dcivision.dms.DmsOperationConstant;
import com.dcivision.dms.EmailAuditTrailConstant;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.dms.bean.DmsDocumentDetail;
import com.dcivision.dms.bean.DmsEmailAuditTrail;
import com.dcivision.dms.bean.DmsVersion;
import com.dcivision.dms.bean.EmailMessageToRule;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.dms.dao.DmsEmailAuditTrailDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.GlobalConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.mail.bean.EmailAttachmentImpl;
import com.dcivision.mail.bean.EmailMessage;
import com.dcivision.mail.bean.EmailMessageImpl;
import com.dcivision.mail.core.EmailReceiver;
import com.dcivision.mail.core.EmailReceiverFactory;
import com.dcivision.mail.core.EmailReceiverImpl;
import com.dcivision.rules.core.RuleManager;
import com.dcivision.user.bean.UserGroup;
import com.dcivision.user.bean.UserRecord;
import com.dcivision.user.dao.UserGroupDAObject;
import com.dcivision.user.dao.UserRecordDAObject;
import com.dcivision.user.dao.UserRoleDAObject;


/**
 * <p>Class Name:       DocumentEmailArchiveManager.java    </p>
 * <p>Description:      The class mainly handle the email archive  process .</p>
 * @author              Beyond Qu
 * @company             DCIVision Limited
 * @creation date       13/06/2005
 * @version             $Revision: 1.38.2.1 $
 */

public class DocumentEmailArchiveManager {

  public static final String REVISION = "$Revision: 1.38.2.1 $";

  private final String REPLACE_INVALID_CHAR = " ";
  private int fileNameIndex;
  
//  protected Log log = LogFactory.getLog(this.getClass().getName());
  protected Log log = new LogFactoryImpl().getInstance(this.getClass());  
  private SessionContainer sessionContainer;
  private Connection conn;
  private String mailServerType = ""; 
  private static String EMAIL_ARCHIVE_DOC_TYPE = DmsDocument.EMAIL_DOC_TYPE;
  private static String EMAIL_ARCHIVE_ORIGEMAIL_TYPE = DmsDocument.ORIGINSLITY_EMAIL_TYPE;
  
  /**
   *  Constructor - Creates a new instance of DocumentEmailArchiveManager
   */
  public DocumentEmailArchiveManager(SessionContainer sessionContainer, Connection conn,String serverType) {
    this.sessionContainer = sessionContainer;
    this.conn = conn;
    this.mailServerType = serverType;
  }

  /**
   *  Release - release all variable in instance of DocumentEmailArchiveManager
   */
  public synchronized void release() {
    this.sessionContainer = null;
    this.conn = null;
  }

  public String getMailServerType() { 
  return(this.mailServerType);
  }

  public void setMailServerType(String mailServerType) { 
    this.mailServerType = mailServerType;
  }  

  /**
   * saveEmailListAsCompundDocuments
   * @param request
   * @throws ApplicationException
  */
  public void saveEmailListAsCompundDocuments(HttpServletRequest request) throws ApplicationException {
    String messageIDs[] = request.getParameterValues("basicSelectedID");
    //save selected email

    List list = new ArrayList();
    for (int i = 0; i < messageIDs.length; i++) {
      EmailMessageImpl emailMessage = (EmailMessageImpl)getMessageContent(request,messageIDs[i],this.mailServerType);
      if (emailMessage != null) {
        String mailSubject = request.getParameter("mailSubject"+ messageIDs[i]);
        if (mailSubject != null) {
          emailMessage.setSubject(mailSubject.trim());
        }
        saveEmailWithAttachmentsAsCompoundDocument(emailMessage,request,true);
        try{
        	 Date sentDate = emailMessage.getSendDate();
        	 String sentDates = TextUtility.getDBDateTimeFormat().format(sentDate);
        	 DmsEmailAuditTrail dmsEmailAuditTrail = new DmsEmailAuditTrail();
           DmsEmailAuditTrailDAObject emailDAO = new DmsEmailAuditTrailDAObject(sessionContainer,conn);
           dmsEmailAuditTrail.setUserid(sessionContainer.getUserRecordID());
           dmsEmailAuditTrail.setOperation(EmailAuditTrailConstant.OPERATION_EMAIL_ARCHIVE);
           dmsEmailAuditTrail.setEmailType(EmailAuditTrailConstant.EMAIL_TYPE_INBOUND);
           dmsEmailAuditTrail.setEmailFrom(emailMessage.getSender());
           dmsEmailAuditTrail.setEmailTo(emailMessage.getTo());
           dmsEmailAuditTrail.setEmailCc(emailMessage.getCc());
           dmsEmailAuditTrail.setEmailBcc("");
           dmsEmailAuditTrail.setEmailSubject(emailMessage.getSubject());
           dmsEmailAuditTrail.setAttchSource("DMS");
           List attchList = new ArrayList();
           attchList = emailMessage.getAttachments();
           Iterator iter = attchList.iterator();
           StringBuffer sb = new StringBuffer();
           while(iter.hasNext()){
          	EmailAttachmentImpl attch = (EmailAttachmentImpl)iter.next();
           	String attchName = attch.getAttachFileName();
           	sb.append(attchName+" ; ");
           }
           dmsEmailAuditTrail.setAttchName(sb.toString());
           dmsEmailAuditTrail.setSentDate(sentDates);
           dmsEmailAuditTrail.setAttchCount(new Integer(attchList.size()));
           dmsEmailAuditTrail.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
      	   dmsEmailAuditTrail.setCreatorID(sessionContainer.getUserRecordID());
      	   dmsEmailAuditTrail.setCreateDate(Utility.getCurrentTimestamp());
      	   dmsEmailAuditTrail.setUpdateCount(new Integer(0));
      	   dmsEmailAuditTrail.setUpdaterID(sessionContainer.getUserRecordID());
      	   dmsEmailAuditTrail.setUpdateDate(Utility.getCurrentTimestamp());
           dmsEmailAuditTrail = (DmsEmailAuditTrail)emailDAO.insertObject(dmsEmailAuditTrail);
        }catch(Exception  e){
          log.error(e, e);
        }
      }
    }
      
    List emailList = (List) request.getSession().getAttribute("sessEmailList");    
    // here is replace the sessEmailList, if saved email will be marked
    for (int i = 0; i < emailList.size(); i++) {
      EmailMessageImpl email = (EmailMessageImpl) emailList.get(i);
      for (int j = 0; j < messageIDs.length; j++) {
        if (messageIDs[j].equals(email.getID().toString())) {
          email.setIsSaved(true);            
        }
      }
      list.add(email);
    }
    request.getSession(true).setAttribute("sessEmailList", list);
  }  
      
  
  /**
   * saveEmailWithAttachmentsAsCompoundDocument,use at save mulit email
   * @param mailMessage
   * @param request
   * @throws ApplicationException
  */
  private void saveEmailWithAttachmentsAsCompoundDocument(EmailMessage mailMessage,HttpServletRequest request,boolean allAttachments)throws ApplicationException {
    DmsDocument newDocument = saveMailContent(mailMessage,request);
    saveAttachments(mailMessage, newDocument, request,allAttachments);
  }
  
  /**
   * saveMailContent
   * @param mailMessage
   * @param request
   * @return
   * @throws ApplicationException
  */
  private DmsDocument saveMailContent(EmailMessage mailMessage,HttpServletRequest request) throws ApplicationException {
    DmsDocument newDocument = null;
    try{
      Integer parentID;
      Integer rootID;
      int fileNameLength = TextUtility.parseInteger(SystemParameterFactory
                  .getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));        
      Integer userRecordID;
      rootID = TextUtility.parseIntegerObj(request.getParameter("targetRootID"));
      parentID = TextUtility.parseIntegerObj(request.getParameter("destinationID"));
      String autoCutFileName = request.getParameter("autoCutFileName") ;
      String subjectStr = "";
      userRecordID = this.sessionContainer.getUserRecordID();
      DocumentOperationManager documentOperationManager = new DocumentOperationManager(this.sessionContainer, this.conn);
      InputStream inputStream;

      DmsDocument dmsDocument = new DmsDocument();
      dmsDocument.setOwnerID(userRecordID);
      dmsDocument.setParentID(parentID);
      dmsDocument.setRootID(rootID);
      subjectStr = mailMessage.getSubject();
      if(subjectStr.length() > fileNameLength){
        subjectStr = subjectStr.substring(0,fileNameLength-8);
      }
        
      String fileExpand = "html";
      if(EmailMessage.EMAIL_CONTENT_TYPE_TXT.equals(mailMessage.getEmailContentType()) ){
        //fileExpand = mailMessage.getEmailContentType();    
      }
      subjectStr = TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR)+"."+fileExpand ;
      dmsDocument.setDocumentName(TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR)+ ".html");
      dmsDocument.setDocumentName(subjectStr);              
      dmsDocument.setDocumentType(EMAIL_ARCHIVE_DOC_TYPE);
      dmsDocument.setCreateType(DmsOperationConstant.DMS_CREATE_BY_SYSTEM);
      dmsDocument.setItemStatus(DmsVersion.AVAILABLE_STATUS);
      dmsDocument.setItemSize(new Integer(mailMessage.getSize()));
      dmsDocument.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
      dmsDocument.setPriority(GlobalConstant.PRIORITY_MEDIUM);
      dmsDocument.setExtRef(mailMessage.getMessageID());      
      String priority;
      int intPriority = mailMessage.getPriority();
      if (EmailReceiver.PRIORITY_HIGH==intPriority || EmailReceiver.PRIORITY_HIGHEST==intPriority) {
        priority = GlobalConstant.PRIORITY_HIGH;
      }else if (EmailReceiver.PRIORITY_NORMAL==intPriority) {
        priority = GlobalConstant.PRIORITY_MEDIUM;
      }else if(EmailReceiver.PRIORITY_LOW==intPriority || EmailReceiver.PRIORITY_LOWEST==intPriority) {
        priority = GlobalConstant.PRIORITY_LOW;
      }else {
        priority = GlobalConstant.PRIORITY_MEDIUM;
      }
      dmsDocument.setPriority(priority);     //taohuaqing  2006-4-10
      String emailContent = this.getEmailContent(mailMessage.getContent());
      inputStream = new DataInputStream(new ByteArrayInputStream(emailContent.getBytes("utf-8")));

      List detailList = new ArrayList();
      String emailUDFProfileID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_ID);
      String emailUDFMailFromID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_MAILFROM_ID);
      String emailUDFMailToID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_MAILTO_ID);
      String emailUDFCCToID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_CCTO_ID);
      String emailUDFSubjectID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_SUBJECT_ID);
      String emailUDFSendDateID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_MAILSENDDATE_ID);

      if (!Utility.isEmpty(emailUDFProfileID)) {
        Integer emailUDFProfileIDInt = new Integer(emailUDFProfileID);
        if (!Utility.isEmpty(emailUDFMailFromID)) {
            DmsDocumentDetail docDetail = new DmsDocumentDetail();
            docDetail.setRecordStatus("A");
            docDetail.setFieldValue(mailMessage.getSender());
            docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFMailFromID));
            docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
            detailList.add(docDetail);
        }

        if (!Utility.isEmpty(emailUDFMailToID)) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          String to = mailMessage.getTo();//barbin 2006-6-20
          if(to.length()>4000){
        	  to = to.substring(1,4000);
          }
          docDetail.setRecordStatus("A");
          docDetail.setFieldValue(to);
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFMailToID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }

        if (!Utility.isEmpty(emailUDFCCToID)) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          String cc = mailMessage.getCc();
          if(cc.length()>4000){//barbin 2006-6-20
        	  cc = cc.substring(1,4000);
          }
          docDetail.setRecordStatus("A");
          docDetail.setFieldValue(cc);
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFCCToID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }

        if (!Utility.isEmpty(emailUDFSubjectID)) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          docDetail.setRecordStatus("A");
          docDetail.setFieldValue(mailMessage.getSubject());
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFSubjectID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }

        if (!Utility.isEmpty(emailUDFSendDateID) && mailMessage.getSendDate()!=null) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          docDetail.setRecordStatus("A");
          docDetail.setFieldValue((new java.sql.Timestamp(mailMessage.getSendDate().getTime())).toString());
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFSendDateID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }
      }

      dmsDocument.setDocumentDetails(detailList);
      
      /********************************************************************
       * barbin 2006-8-26
       * function: checked the documentName . auto +1 operation
       * EIP_97
       */
      try{
   	   	DocumentValidateManager manager = new DocumentValidateManager(sessionContainer,conn);
	      String oldFileName = dmsDocument.getDocumentName();
	      String newFileName = dmsDocument.getDocumentName();
	      String fileNameOri = oldFileName.substring(0,oldFileName.lastIndexOf("."));
	      String fileNameExt = oldFileName.substring(oldFileName.lastIndexOf("."));
	      int fileNameRenameIndex = 1;
	      boolean checDuplicate = true;
   	    do{
	   		 dmsDocument.setDocumentName(newFileName);
	   		 checDuplicate = manager.checkNameExistence(dmsDocument);
	   		 newFileName = fileNameOri + "("+ fileNameRenameIndex+ ")" + fileNameExt;      
   	     fileNameRenameIndex++; 
   	   }while(checDuplicate==true); 
      }catch(Exception e){
        log.error(e, e);
      }
      newDocument = documentOperationManager.createDocument(dmsDocument, inputStream);
      conn.commit() ;
    }catch(Exception e){
      log.error(e, e);
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_SAVE_EMAIL_TO_DMS);
    }
    return newDocument;      
  }

  /**
   * saveMailContent -- used for email archive tracker action
   * @param mailMessage
   * @param rootIDStr
   * @param parentIDStr
   * @return
   * @throws ApplicationException
  */
  public DmsDocument saveMailContent(EmailMessageImpl mailMessage,String rootIDStr,String parentIDStr) throws ApplicationException {
    DmsDocument newDocument = null;
    try{
      Integer parentID;
      Integer rootID;
      int fileNameLength = TextUtility.parseInteger(SystemParameterFactory
                  .getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));        
      Integer userRecordID;
      rootID = TextUtility.parseIntegerObj(rootIDStr);
      parentID = TextUtility.parseIntegerObj(parentIDStr);
      String autoCutFileName = "true" ;
      String subjectStr = "";
      
      userRecordID = this.sessionContainer.getUserRecordID();
      DocumentOperationManager documentOperationManager = new DocumentOperationManager(this.sessionContainer, this.conn);
      InputStream inputStream;

      DmsDocument dmsDocument = new DmsDocument();
      dmsDocument.setOwnerID(userRecordID);
      dmsDocument.setParentID(parentID);
      dmsDocument.setRootID(rootID);
      subjectStr = mailMessage.getSubject();    
      if(subjectStr.length() > fileNameLength){          
        subjectStr = subjectStr.substring(0,fileNameLength-5);
      }
//      subjectStr = TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR);      
//      String fileExpand = "html";
//      if(EmailMessage.EMAIL_CONTENT_TYPE_TXT.equals(mailMessage.getEmailContentType()) ){
//        fileExpand = mailMessage.getEmailContentType();    
//      }
//      subjectStr = subjectStr+fileExpand;
      dmsDocument.setDocumentName(TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR));
      //dmsDocument.setDocumentName(subjectStr);        
      dmsDocument.setDocumentType(EMAIL_ARCHIVE_DOC_TYPE);
      dmsDocument.setCreateType(DmsOperationConstant.DMS_CREATE_BY_SYSTEM);
      dmsDocument.setItemStatus(DmsVersion.AVAILABLE_STATUS);
      dmsDocument.setItemSize(new Integer(mailMessage.getSize()));
      dmsDocument.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
      dmsDocument.setPriority(GlobalConstant.PRIORITY_MEDIUM);
      dmsDocument.setExtRef(mailMessage.getMessageID());
      String emailContent = this.getEmailContent(mailMessage.getContent());
      inputStream = new DataInputStream(new ByteArrayInputStream(emailContent.getBytes("UTF-8")));

      List detailList = new ArrayList();
      String emailUDFProfileID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_ID);
      String emailUDFMailFromID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_MAILFROM_ID);
      String emailUDFMailToID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_MAILTO_ID);
      String emailUDFCCToID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_CCTO_ID);
      String emailUDFSubjectID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_SUBJECT_ID);
      String emailUDFSendDateID = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_PROFILE_EMAIL_DETAIL_MAILSENDDATE_ID);

      if (!Utility.isEmpty(emailUDFProfileID)) {
        Integer emailUDFProfileIDInt = new Integer(emailUDFProfileID);
        // set Sender
        if (!Utility.isEmpty(emailUDFMailFromID)) {
            DmsDocumentDetail docDetail = new DmsDocumentDetail();
            docDetail.setRecordStatus("A");
            docDetail.setFieldValue(mailMessage.getSender());
            docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFMailFromID));
            docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
            detailList.add(docDetail);
        }
        
        // set To
        if (!Utility.isEmpty(emailUDFMailToID)) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          docDetail.setRecordStatus("A");
          String toValue = mailMessage.getTo();
          if(toValue.length()>4000){
        	  toValue = toValue.substring(1,4000);
          }
          docDetail.setFieldValue(toValue);
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFMailToID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }
        
        // set CC
        if (!Utility.isEmpty(emailUDFCCToID)) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          docDetail.setRecordStatus("A");
          String ccValue = mailMessage.getTo();
          if(ccValue.length()>4000){
        	  ccValue = ccValue.substring(1,4000);
          }
          docDetail.setFieldValue(ccValue);
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFCCToID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }
        // set Subject
        if (!Utility.isEmpty(emailUDFSubjectID)) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          docDetail.setRecordStatus("A");
          docDetail.setFieldValue(mailMessage.getOriSubject());
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFSubjectID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }
        
        // set Senddate
        if (!Utility.isEmpty(emailUDFSendDateID) && mailMessage.getSendDate()!=null) {
          DmsDocumentDetail docDetail = new DmsDocumentDetail();
          docDetail.setRecordStatus("A");
          docDetail.setFieldValue((new java.sql.Timestamp(mailMessage.getSendDate().getTime())).toString());
          docDetail.setUserDefinedFieldDetailID(new Integer(emailUDFSendDateID));
          docDetail.setUserDefinedFieldID(emailUDFProfileIDInt);
          detailList.add(docDetail);
        }
      }
      dmsDocument.setDocumentDetails(detailList);
      newDocument = documentOperationManager.createDocument(dmsDocument, inputStream);
      conn.commit() ;
    }catch(Exception e){
      log.error(e, e);
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_SAVE_EMAIL_TO_DMS);
    }
    return newDocument;      
  }  
  
  
  /**
   * saveAttachments
   * @param mailMessage
   * @param newDocument
   * @param allAttachments (if at list page save email,this param value is "true" else at view single email
   *  page save save email ,this param value is "false"  )
   * @param request
   * @throws ApplicationException
   */
  private void saveAttachments(EmailMessage mailMessage,DmsDocument newDocument, HttpServletRequest request,boolean saveAllAttachments)throws ApplicationException {
    Integer userRecordID;
    Integer rootID;
    rootID = TextUtility.parseIntegerObj(request.getParameter("targetRootID"));
    userRecordID = this.sessionContainer.getUserRecordID();
    DocumentOperationManager documentOperationManager = new DocumentOperationManager(this.sessionContainer, this.conn);
    String replacedContentString = mailMessage.getOriContent();    
    int fileNameLength = TextUtility.parseInteger(SystemParameterFactory
        .getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));            
    
    List attachmentList = mailMessage.getAttachments();
    List newList = new ArrayList();
    newList = this.changeAttachmentNameList(attachmentList);
    for (int i = 0; i < newList.size(); i++) {
      if ( saveAllAttachments || this.isSelectedAttachment(i, request)) {
        EmailAttachmentImpl attachment = (EmailAttachmentImpl) newList.get(i);
        Integer parentID = newDocument.getID();
        
        String subjectStr = attachment.getAttachFileName();
        String fileExpand = "";
        if(subjectStr.indexOf(".")>0){
          fileExpand  = subjectStr.substring(subjectStr.lastIndexOf("."),subjectStr.length());            
        } 
        
        if(subjectStr.length() > fileNameLength){
          subjectStr = subjectStr.substring(0,fileNameLength-5);
          subjectStr = subjectStr+  fileExpand;          
        }
        
        subjectStr = TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR);      

        try {
          DmsDocument document = new DmsDocument();
          document.setDocumentName(subjectStr);
          document.setParentID(parentID);
          document.setOwnerID(userRecordID);
          document.setRootID(rootID);
          
          if(attachment.getIsOrigEmail()){
            document.setDocumentType(EMAIL_ARCHIVE_ORIGEMAIL_TYPE);          
          }else{
            document.setDocumentType(DmsDocument.DOCUMENT_TYPE);          
          }
          document.setCreateType(DmsOperationConstant.DMS_CREATE_BY_SYSTEM);
          document.setItemStatus(DmsVersion.AVAILABLE_STATUS);
          document.setItemSize(new Integer(attachment.getFileSize()));
          document.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
//          documentOperationManager.createDocument(document,getAttachmentFileInputSteam(attachment));
          DmsDocument newAttachmentDocument = documentOperationManager.createDocument(document,getAttachmentFileInputSteam(attachment));
          // replace the document content if is html doc and have images,replace the "cid:xxx" url to sub doc's content url
          if(mailMessage.getOriContent()!=null&&!mailMessage.getOriContent().equals(mailMessage.getContent().toString())){
            String contentId = attachment.getContentID();
            if (contentId != null) {
          	  // remove "<"">"
          	if(contentId.indexOf("<") !=-1){
                  contentId =  contentId.substring(1,contentId.length()-1);        		
          	}  
              
              String baseUrl = com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.APPLICATION_BASE_URL);
              String getContentUrl = baseUrl+ "/dms/emailArchiveGetImage?"+ "attachmentDocumentID="+ newAttachmentDocument.getID();
              if(!Utility.isEmpty(replacedContentString)){               	
                replacedContentString = TextUtility.replaceString(replacedContentString, "cid:"+ contentId, getContentUrl);
              }
            }
          }          
          
        } catch (Exception ex) {
          log.error(ex, ex);
          throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_SAVE_EMAIL_TO_DMS);                
        }
      }
    }
      
      if(mailMessage.getOriContent()!=null&&!mailMessage.getOriContent().equals(mailMessage.getContent().toString())){
        try{ 
     	    documentOperationManager.replaceDocPhysicalFileContent(newDocument,replacedContentString);
        }catch(Exception e){
          throw new ApplicationException(DmsErrorConstant.PHYSICAL_FILE_NOT_FOUND,e);
        }    
      }
  }
  
  /**
   * saveAttachments
   * @param mailMessage
   * @param newDocument
   * @param allAttachments (if at list page save email,this param value is "true" else at view single email
   *  page save save email ,this param value is "false"  )
   * @param request
   * @throws ApplicationException
   */
  public void saveAttachments(EmailMessage mailMessage,DmsDocument newDocument,String rootIDStr,String parentIDStr)throws ApplicationException {
    Integer userRecordID;
    Integer rootID;
    rootID = TextUtility.parseIntegerObj(rootIDStr);
    userRecordID = this.sessionContainer.getUserRecordID();
    DocumentOperationManager documentOperationManager = new DocumentOperationManager(this.sessionContainer, this.conn);
    int fileNameLength = TextUtility.parseInteger(SystemParameterFactory
        .getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));      
    
    List attachmentList = mailMessage.getAttachments();
    List newList = new ArrayList();
    newList = this.changeAttachmentNameList(attachmentList);
    String replacedContentString ="";
//    String contentString = mailMessage.getOriContent();    
    replacedContentString = mailMessage.getOriContent();    
    for (int i = 0; i < newList.size(); i++) {
      EmailAttachmentImpl attachment = (EmailAttachmentImpl) newList.get(i);
      Integer parentID = newDocument.getID();
      
      String subjectStr = attachment.getAttachFileName();
      String fileExpand = "";
      if(subjectStr.indexOf(".")>0){
        fileExpand  = subjectStr.substring(subjectStr.lastIndexOf("."),subjectStr.length());            
      } 
      
      if(subjectStr.length() > fileNameLength){
        subjectStr = subjectStr.substring(0,fileNameLength/2);
        subjectStr = subjectStr+  fileExpand;        
      }
      
      subjectStr = TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR);      

      
      try {
        DmsDocument document = new DmsDocument();
        document.setDocumentName(subjectStr);
        document.setParentID(parentID);
        document.setOwnerID(userRecordID);
        document.setRootID(rootID);
        if(attachment.getIsOrigEmail()){
          document.setDocumentType(EMAIL_ARCHIVE_ORIGEMAIL_TYPE);          
        }else{
          document.setDocumentType(DmsDocument.DOCUMENT_TYPE);          
        }
        document.setCreateType(DmsOperationConstant.DMS_CREATE_BY_SYSTEM);
        document.setItemStatus(DmsVersion.AVAILABLE_STATUS);
        document.setItemSize(new Integer(attachment.getFileSize()));
        document.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
        DmsDocument newAttachmentDocument = documentOperationManager.createDocument(document,getAttachmentFileInputSteam(attachment));
        // replace the document content if is html doc and have images,replace the "cid:xxx" url to sub doc's content url
        if(!mailMessage.getOriContent().equals(mailMessage.getContent().toString())){
          String contentId = attachment.getContentID();
          if (contentId != null) {
        	  // remove "<"">"
        	if(contentId.indexOf("<") !=-1){
                contentId =  contentId.substring(1,contentId.length()-1);        		
        	}  
            
            String baseUrl = com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.APPLICATION_BASE_URL);
            String getContentUrl = baseUrl+ "/dms/emailArchiveGetImage?"+ "attachmentDocumentID="+ newAttachmentDocument.getID();
            if(!Utility.isEmpty(replacedContentString)){               	
              replacedContentString = TextUtility.replaceString(replacedContentString, "cid:"+ contentId, getContentUrl);
            }
          }
        }          
        
      } catch (Exception ex) {
        log.error(ex, ex);
        throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_SAVE_EMAIL_TO_DMS);                
      }
    }
    
    if(!mailMessage.getOriContent().equals(mailMessage.getContent().toString())){
      try{
   	    documentOperationManager.replaceDocPhysicalFileContent(newDocument,replacedContentString);
      }catch(Exception e){
        throw new ApplicationException(DmsErrorConstant.PHYSICAL_FILE_NOT_FOUND,e);
      }    
    }
    
    
  }

  
  
  /**
   * isSelectedAttachment
   * @param no
   * @param request
   * @return
  */
  private boolean isSelectedAttachment(int no, HttpServletRequest request) {
    String selectAttachments[] = request.getParameterValues("attachment");
    if (selectAttachments == null || selectAttachments.length == 0) {
      return false;
    }

    for (int i = 0; i < selectAttachments.length; i++) {
      if (no == Integer.parseInt(selectAttachments[i])) {
        return true;
      }
    }
    return false;
  }


  /**
   * getEmailContent
   * @param content
   * @return
  */
  private String getEmailContent(Object content) throws ApplicationException {
    try {
      if (content.getClass().getName().equals("javax.mail.internet.MimeMultipart")) {
        MimeMultipart multiContent = (MimeMultipart) content;
        for (int m = 0; m < multiContent.getCount(); m++) {
          BodyPart part = multiContent.getBodyPart(m);
          return part.getContent().toString();
        }
      } else {
        return content.toString();
      }
    } catch (Exception ex) {
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_TO_GET_EMAIL_CONTENT);                  
    }
    return "";
  }
  
  
  /**
   * saveEmailWithSelectedAttachmentsAsCompoundDocument  ,use at save a single email
   * @param request
   * @throws ApplicationException
  */
  public void saveEmailWithSelectedAttachmentsAsCompoundDocument(HttpServletRequest request)throws ApplicationException {
    try {
      EmailMessage mailMessage = getCurrentEmailMessage(request);
      // if have new subject name replace the old name
      String mailSubject = request.getParameter("mailSubject"+ mailMessage.getID());
      if (mailSubject != null) {
        mailMessage.setSubject(mailSubject.trim());
      }      
      saveEmailWithAttachmentsAsCompoundDocument(mailMessage,request,false);
      
      try{
     	  Date sentDate = mailMessage.getSendDate();
     	  DmsEmailAuditTrail dmsEmailAuditTrail = new DmsEmailAuditTrail();
        DmsEmailAuditTrailDAObject emailDAO = new DmsEmailAuditTrailDAObject(sessionContainer,conn);
        dmsEmailAuditTrail.setUserid(sessionContainer.getUserRecordID());
        dmsEmailAuditTrail.setOperation(EmailAuditTrailConstant.OPERATION_EMAIL_ARCHIVE);
        dmsEmailAuditTrail.setEmailType(EmailAuditTrailConstant.EMAIL_TYPE_INBOUND);
        dmsEmailAuditTrail.setEmailFrom(mailMessage.getSender());
        dmsEmailAuditTrail.setEmailTo(mailMessage.getTo());
        dmsEmailAuditTrail.setEmailCc(mailMessage.getCc());
        dmsEmailAuditTrail.setEmailBcc("");
        dmsEmailAuditTrail.setEmailSubject(mailMessage.getSubject());
        dmsEmailAuditTrail.setAttchSource("DMS");
        List attchList = new ArrayList();
        attchList = mailMessage.getAttachments();
        Iterator iter = attchList.iterator();
        StringBuffer sb = new StringBuffer();
        while(iter.hasNext()){
       	  EmailAttachmentImpl attch = (EmailAttachmentImpl)iter.next();
        	String attchName = attch.getAttachFileName();
        	sb.append(attchName+" ; ");
        }
        dmsEmailAuditTrail.setAttchName(sb.toString());
        dmsEmailAuditTrail.setSentDate(TextUtility.getDBDateTimeFormat().format(sentDate));
        dmsEmailAuditTrail.setAttchCount(new Integer(attchList.size()));
        dmsEmailAuditTrail.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
   	    dmsEmailAuditTrail.setCreatorID(sessionContainer.getUserRecordID());
   	    dmsEmailAuditTrail.setCreateDate(Utility.getCurrentTimestamp());
   	    dmsEmailAuditTrail.setUpdateCount(new Integer(0));
   	    dmsEmailAuditTrail.setUpdaterID(sessionContainer.getUserRecordID());
   	    dmsEmailAuditTrail.setUpdateDate(Utility.getCurrentTimestamp());
        dmsEmailAuditTrail = (DmsEmailAuditTrail)emailDAO.insertObject(dmsEmailAuditTrail);
     }catch(Exception  e){
       log.error(e, e);
     }
      
      List list = new ArrayList();
      String mailID = request.getParameter("basicSelectedID");
      List emailList = (List) request.getSession().getAttribute("sessEmailList");    
      // here is replace the sessEmailList, if saved email will be marked
      for (int i = 0; i < emailList.size(); i++) {
        EmailMessageImpl email = (EmailMessageImpl) emailList.get(i);
        if (mailID.equals(email.getID().toString())) {
          email.setIsSaved(true);            
        }
        list.add(email);
      }
      request.getSession(true).setAttribute("sessEmailList", list);      
    } catch (Exception ex) {
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_SAVE_EMAIL_TO_DMS);
    }
  }

  /**
   * saveAttachmentsAsDocuments
   * @param request
   * @throws ApplicationException
  */
  public void saveAttachmentsAsDocuments(HttpServletRequest request) throws ApplicationException {
    try {
      Integer rootID = TextUtility.parseIntegerObj(request.getParameter("targetRootID"));
      Integer parentID = TextUtility.parseIntegerObj(request.getParameter("destinationID"));
      DocumentOperationManager documentOperationManager = new DocumentOperationManager(this.sessionContainer, this.conn);
      String mailID = request.getParameter("mailID");           
      List mailList = (List) request.getSession(true).getAttribute("sessEmailList");
      EmailMessage emailMessage = EmailReceiver.getMailByID(mailList, mailID);
      List attachmentList = emailMessage.getAttachments();
      int fileNameLength = TextUtility.parseInteger(SystemParameterFactory
          .getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));  

      
      
      List newList = new ArrayList();
      newList = this.changeAttachmentNameList(attachmentList);
      DocumentValidateManager manager = new DocumentValidateManager(this.sessionContainer, this.conn);
      
      for (int i = 0; i < newList.size(); i++) {        
        if(isSelectedAttachment(i, request)){
          DmsDocument document = new DmsDocument();
          EmailAttachmentImpl attachment = (EmailAttachmentImpl) newList.get(i);
          
          String subjectStr = attachment.getAttachFileName();
          String fileExpand = "";
          if(subjectStr.indexOf(".")>0){
            fileExpand  = subjectStr.substring(subjectStr.lastIndexOf("."),subjectStr.length());            
          } 
          
          if(subjectStr.length() > fileNameLength){
            subjectStr = subjectStr.substring(0,fileNameLength-5);
            subjectStr = subjectStr+  fileExpand;            
          }
          
          subjectStr = TextUtility.replaceInvalidChar(subjectStr,REPLACE_INVALID_CHAR);      

          
          document.setDocumentName(subjectStr);
          document.setParentID(parentID);
          document.setOwnerID(this.sessionContainer.getUserRecordID());
          document.setRootID(rootID);
          document.setDocumentType(DmsDocument.DOCUMENT_TYPE);  
          document.setCreateType(DmsOperationConstant.DMS_CREATE_BY_SYSTEM);
          document.setItemStatus(DmsVersion.AVAILABLE_STATUS);
          document.setItemSize(new Integer(attachment.getFileSize()));
          document.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
          boolean checDuplicate = manager.checkNameExistence(document);
          if (!checDuplicate) {
            document.setDocumentName(subjectStr);
            document.setParentID(parentID);
            document.setOwnerID(this.sessionContainer.getUserRecordID());
            document.setRootID(rootID);
            document.setDocumentType(DmsDocument.DOCUMENT_TYPE); 
            document.setCreateType(DmsOperationConstant.DMS_CREATE_BY_SYSTEM);
            document.setItemStatus(DmsVersion.AVAILABLE_STATUS);
            document.setItemSize(new Integer(attachment.getFileSize()));
            document.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
//        newDocument = documentOperationManager.createDocument(document,getAttachmentFileInputSteam(attachment));
            documentOperationManager.createDocument(document,getAttachmentFileInputSteam(attachment));  
            
          }else{
            throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_DUPLICATE_EMAIL_SUBJECT_ERROR);
          }
        }  
      }

      try{
     	  Date sentDate = emailMessage.getSendDate();
     	  DmsEmailAuditTrail dmsEmailAuditTrail = new DmsEmailAuditTrail();
        DmsEmailAuditTrailDAObject emailDAO = new DmsEmailAuditTrailDAObject(sessionContainer,conn);
        dmsEmailAuditTrail.setUserid(sessionContainer.getUserRecordID());
        dmsEmailAuditTrail.setOperation(EmailAuditTrailConstant.OPERATION_EMAIL_ARCHIVE);
        dmsEmailAuditTrail.setEmailType(EmailAuditTrailConstant.EMAIL_TYPE_INBOUND);
        dmsEmailAuditTrail.setEmailFrom(emailMessage.getSender());
        dmsEmailAuditTrail.setEmailTo(emailMessage.getTo());
        dmsEmailAuditTrail.setEmailCc(emailMessage.getCc());
        dmsEmailAuditTrail.setEmailBcc("");
        dmsEmailAuditTrail.setEmailSubject(emailMessage.getSubject());
        dmsEmailAuditTrail.setAttchSource("DMS");
        List attchList = new ArrayList();
        attchList = emailMessage.getAttachments();
        Iterator iter = attchList.iterator();
        StringBuffer sb = new StringBuffer();
        while(iter.hasNext()){
       	  EmailAttachmentImpl attch = (EmailAttachmentImpl)iter.next();
        	String attchName = attch.getAttachFileName();
        	sb.append(attchName+" ; ");
        }
        dmsEmailAuditTrail.setAttchName(sb.toString());
        dmsEmailAuditTrail.setSentDate(TextUtility.getDBDateTimeFormat().format(sentDate));
        dmsEmailAuditTrail.setAttchCount(new Integer(attchList.size()));
        dmsEmailAuditTrail.setRecordStatus(GlobalConstant.RECORD_STATUS_ACTIVE);
   	    dmsEmailAuditTrail.setCreatorID(sessionContainer.getUserRecordID());
   	    dmsEmailAuditTrail.setCreateDate(Utility.getCurrentTimestamp());
   	    dmsEmailAuditTrail.setUpdateCount(new Integer(0));
   	    dmsEmailAuditTrail.setUpdaterID(sessionContainer.getUserRecordID());
   	    dmsEmailAuditTrail.setUpdateDate(Utility.getCurrentTimestamp());
        dmsEmailAuditTrail = (DmsEmailAuditTrail)emailDAO.insertObject(dmsEmailAuditTrail);
     }catch(Exception  e){
       log.error(e, e);
     }
    } catch (ApplicationException e) {
       throw e;
    } catch (Exception e) {
      throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_SAVE_EMAIL_TO_DMS);                
    }
  }


  /**
   * getCurrentEmailMessage
   * @param request
   * @return
   * @throws ApplicationException
   */
  private EmailMessage getCurrentEmailMessage(HttpServletRequest request) throws ApplicationException{
    try {
      List mailList = (List) request.getSession(true).getAttribute("sessEmailList");
      String mailID = request.getParameter("basicSelectedID");
      return EmailReceiver.getMailByID(mailList, mailID);
    } catch (Exception e) {
       throw new ApplicationException(DmsErrorConstant.MESSAGE_EMAILARCHIVE_FAIL_TO_GET_EMAIL_CONTENT);
    }
  }


  /**
   * changeAttachmentNameList
   * @param list
   * @return
  */
  private List changeAttachmentNameList(List list) {
    List newList = new ArrayList();
    String newName = "";
    for (int i = 0; i < list.size(); i++) {
      EmailAttachmentImpl emailAttachment = (EmailAttachmentImpl) list.get(i);
      newName = this.changeAttachmentName(newList, emailAttachment.getAttachFileName());
      emailAttachment.setAttachFileName(newName);
      newList.add(emailAttachment);
    }
    return newList;
  }

  /**
   * changeAttachmentName
   * @param list
   * @param name
   * @return
 */
  private String changeAttachmentName(List list, String name) {
    for (int i = 0; i < list.size(); i++) {
      EmailAttachmentImpl emailAttachment = (EmailAttachmentImpl) list.get(i);
      if (name.equals(emailAttachment.getAttachFileName())) {
        fileNameIndex++;
        name = changeAttachmentName(list, name.substring(0, name
          .indexOf("."))+ "("+ fileNameIndex+ ")"+ name.substring(name.indexOf("."), name.length()));
          break;
      }
    }
    return name;
  }
    
    
  /**
   * getMessageContent
   * @param request
   * @param mailid
   * @param mailServerType
   * @return
   * @throws ApplicationException
   */
  public EmailMessage getMessageContent(HttpServletRequest request,String mailid,String mailServerType) throws ApplicationException{
    EmailReceiver receiver =  EmailReceiverFactory.getEmailReceiverInstanceByServerType(sessionContainer,mailServerType);
    return receiver.getMessageContent(request,mailid,this.mailServerType);
  }
  
  /**
   * getMessageContentNew
   * @param request
   * @param mailid
   * @param mailServerType
   * @return
   * @throws ApplicationException
   */
  public EmailMessage getMessageContentNew(HttpServletRequest request,EmailMessage emailMessage,String mailServerType) throws ApplicationException{
    EmailReceiver receiver =  EmailReceiverFactory.getEmailReceiverInstanceByServerType(sessionContainer,mailServerType);
    return receiver.getMessageContentNew(request,emailMessage,mailServerType);
  }

  /**
   * getAttachmentFileInputSteam
   * @param emailAttachment
   * @return
   * @throws Exception
   */
  private DataInputStream getAttachmentFileInputSteam(EmailAttachmentImpl emailAttachment) throws Exception{
    DataInputStream inputStream =null;      
    String cachePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);
    String trueFilePath = cachePath + emailAttachment.getCatchFileName();
    File file = new File(trueFilePath);
    if (file.exists()) {
      inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(trueFilePath)));
    }
    return inputStream;
  }

  /** Method disposeSubject() if the msg  have same subject at the specify location ,rename the subject  such as abc.txt => abc(1).txt
   * @param sessionContainer
   * dbConn
   * emailMessage
   * rootID
   * parentID
   * @return
   * @throws ApplicationException
   */
  public EmailMessageImpl disposeSubject(SessionContainer sessionContainer,Connection dbConn,EmailMessageImpl emailMessage,String rootID,String parentID) throws ApplicationException {
    DocumentValidateManager manager = new DocumentValidateManager(sessionContainer,dbConn);
    DmsDocument doc = new DmsDocument();
    boolean checDuplicate = true;
    String subject = "";    
    String subjectStr = "";
    String subjectNameMain = "";

    int fileNameRenameIndex = 1;
    int fileNameMaxLength = TextUtility.parseInteger(SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_MAX_UPLOAD_FILENAME_LENGTH));            
    subject = emailMessage.getSubject().trim();
    
    String subjectNameExt = "html";
    if(EmailMessage.EMAIL_CONTENT_TYPE_TXT.equals(emailMessage.getEmailContentType()) ){
      subjectNameExt = emailMessage.getEmailContentType();    
    }    
    
    if(!Utility.isEmpty(emailMessage.getSubject().trim())){      	
  	  subjectNameMain = emailMessage.getSubject().trim();
    }else{
      subjectNameMain = "NotSubject";
    }    
    
    //replace invalid char and substring the subjectNameMain if subjectNameMain leng max than fileNameMaxLength
    subjectNameMain = TextUtility.replaceInvalidChar(subjectNameMain,EmailReceiverImpl.REPLACE_INVALID_CHAR);
    if(subjectNameMain.length()+subjectNameExt.length() > fileNameMaxLength){
      subjectNameMain = subjectNameMain.substring(0,fileNameMaxLength-10);
    }
    subjectStr = subjectNameMain +"."+ subjectNameExt;
//    subjectStr = subjectNameMain;
    
    do{
      emailMessage.setSubject(subjectStr);    	
      doc.setDocumentName(subjectStr);
      doc.setParentID(TextUtility.parseIntegerObj(parentID));
      doc.setRootID(TextUtility.parseIntegerObj(rootID));
      doc.setDocumentType(EMAIL_ARCHIVE_DOC_TYPE);
      doc.setItemStatus("A");
      checDuplicate = manager.checkNameExistence(doc);
      if(checDuplicate){
        subjectStr = subjectNameMain + "("+ fileNameRenameIndex+ ")" + "." + subjectNameExt;      
        fileNameRenameIndex++; 
      }
    }
    while(checDuplicate==true); 
    
    return emailMessage;
  }
  
  /**
   * setEmailListToRule
   * @param request
   * @throws ApplicationException
  */
  public void setEmailListToRule(HttpServletRequest request) throws ApplicationException {
    
    RuleManager ruleManager = null;    
    List emailList = (List) request.getSession().getAttribute("sessEmailList");
    EmailMessageToRule emailMessageToRule = new EmailMessageToRule();
    UserRecordDAObject userRecordDAObject = null ;
    
    try{
      userRecordDAObject = new UserRecordDAObject(sessionContainer,conn) ;
      ruleManager = new RuleManager(sessionContainer, conn);
      for (int i = 0; i < emailList.size(); i++) {
        //EmailMessageImpl emlEmailMessage = (EmailMessageImpl)getMessageContent(request,TextUtility.formatInteger(i),this.mailServerType);
        EmailMessageImpl emlEmailMessage = (EmailMessageImpl)getMessageContentNew(request,(EmailMessage)emailList.get(i),this.mailServerType);
        
        if(emlEmailMessage !=null ){
        
          //set the emlEmailMessage to the emailMessageToRule,the emailMessageToRule will be set to rule Manager
          emailMessageToRule.setEmailMessageData(emlEmailMessage); 
        
          //get user by emailAddressList
          String allEmailAddressUserID = "";
          //if (!Utility.isEmpty(emailAddressList)){
          String senderUserIDStr = "";
          String toUserIDStr = "";
          String ccUserIDStr = "";
          
          String[] toEmailAddressesArr ;
          String[] ccEmailAddressesArr ;            
          
          // get the formated address
          String fromEmailAddress = EmailReceiverImpl.getEmailAdressStr(emlEmailMessage.getSender());
          String toEmailAddresses = EmailReceiverImpl.getEmailAdressStr(emlEmailMessage.getTo());
          String ccEmailAddresses = EmailReceiverImpl.getEmailAdressStr(emlEmailMessage.getCc());
          
          // use sender address get the user's id
          if(!Utility.isEmpty(fromEmailAddress)){
            UserRecord tmpUserRecord = (UserRecord)userRecordDAObject.getUserByEmailAddress(fromEmailAddress);  
            if(tmpUserRecord!=null){
              String tmpStr = getTheUserIDGroupIDRoleIDStrByUserID(tmpUserRecord.getID(),conn);
              if(!Utility.isEmpty(tmpStr)){
                senderUserIDStr += tmpStr+",";
              }
            }
          }
          
          
          // use to address get the user's id
          if(!Utility.isEmpty(toEmailAddresses)){
            toEmailAddressesArr = TextUtility.splitString(toEmailAddresses,",");                
            for(int addrNum = 0 ; addrNum < toEmailAddressesArr.length;addrNum++ ){
              UserRecord tmpUserRecord = (UserRecord)userRecordDAObject.getUserByEmailAddress(toEmailAddressesArr[addrNum]);  
              if(tmpUserRecord!=null){
                String tmpStr = getTheUserIDGroupIDRoleIDStrByUserID(tmpUserRecord.getID(),conn);   
                if(!Utility.isEmpty(tmpStr)){
                  toUserIDStr += tmpStr+",";  
                }                    
              }                  
            }
          }
          
          // use to address get the user's id
          if(!Utility.isEmpty(ccEmailAddresses)){
            ccEmailAddressesArr = TextUtility.splitString(ccEmailAddresses,",");                
            for(int addrNum = 0 ; addrNum < ccEmailAddressesArr.length;addrNum++ ){
              UserRecord tmpUserRecord = (UserRecord)userRecordDAObject.getUserByEmailAddress(ccEmailAddressesArr[addrNum]);  
              if(tmpUserRecord!=null){
                String tmpStr = getTheUserIDGroupIDRoleIDStrByUserID(tmpUserRecord.getID(),conn);                    
                if(!Utility.isEmpty(tmpStr)){
                  ccUserIDStr += tmpStr+",";  
                } 
              }                  
            }
          }              
          
          
          emailMessageToRule.setSenderEmailAddress(fromEmailAddress);
          emailMessageToRule.setToEmailAddress(toEmailAddresses);
          emailMessageToRule.setCcEmailAddress(ccEmailAddresses);
          emailMessageToRule.setSenderUserIDStr(senderUserIDStr);
          emailMessageToRule.setToUserIDStr(toUserIDStr);
          emailMessageToRule.setCcUserIDStr(ccUserIDStr);
          
          // set all email address
          emailMessageToRule.setEmailAllEmailAddress("");              
          
            emailMessageToRule.setEmailAllUserIDStr("");
            
            // call public rule 
            emailMessageToRule.setIsPrivaeteRule(false);
            log.debug("/*****Call Public Rule Start***********/");                                    
            ruleManager.performEmailArchiveRule(emailMessageToRule);
            log.debug("/*****Call Public Rule End***********/");                        
            
            //call private rule
            /*****Call Rule Test Start***********/ 
            emailMessageToRule.setMessgeUserID(sessionContainer.getUserRecordID());      
            emailMessageToRule.setIsPrivaeteRule(true);                    
            log.debug("/*****Call Private Rule  Start***********/");                                    
            ruleManager.performEmailArchiveRule(emailMessageToRule);
            log.debug("/*****Call Private Rule  End***********/");  
            /*****Call Rule Test End***********/
           
        }
      }    
    } catch (Exception e) {
      log.error(e, e);
    }    
  }  
  
  public String getTheUserIDGroupIDRoleIDStrByUserID(Integer userID,Connection connection){
    String userIDsymbol = "U:";
    String groupIDsymbol = "G:";
    String roleIDsymbol = "R:";    
    String userIDGroupIDRoleIDStr = userIDsymbol+userID;    
    try {    
      UserGroupDAObject userGroupDAO = new UserGroupDAObject(this.sessionContainer, connection);
      List listGroup = userGroupDAO.getListByUserRecordIDGroupType(userID, UserGroup.GROUP_TYPE_PUBLIC);
      
      Integer[] iaGroupID = (Integer[])Utility.getPropertyArray(listGroup, "ID", new Integer[0]);
      String[] saGroupID = Utility.getStringArray(iaGroupID);
      if(!Utility.isEmpty(saGroupID)){
        for(int i = 0 ;i < saGroupID.length ; i++){
          userIDGroupIDRoleIDStr += ","+groupIDsymbol+saGroupID[i];          
        }
      }
      
      UserRoleDAObject userRoleDAO = new UserRoleDAObject(this.sessionContainer, connection);
      List listRole = userRoleDAO.getListByUserRecordID(userID);
      Integer[] iaRoleID = (Integer[])Utility.getPropertyArray(listRole, "ID", new Integer[0]);
      String[] saRoleID = Utility.getStringArray(iaRoleID);
      
      if(!Utility.isEmpty(saRoleID)){
        for(int i = 0 ;i < saRoleID.length ; i++){
          userIDGroupIDRoleIDStr += ","+roleIDsymbol+saRoleID[i];          
        }
      }      
    } catch (Exception e) {
      log.error("Retrieve userID groupID roleID.", e);
    }    
    return userIDGroupIDRoleIDStr;    
  }
  
  public void saveWholeEmail(EmailMessageImpl mailMessage,String rootIDStr,String parentIDStr) throws ApplicationException {

    DocumentOperationManager docOperationManager = new DocumentOperationManager(sessionContainer, conn);
    DocumentRetrievalManager docRetrievalManager = new DocumentRetrievalManager(sessionContainer, conn);
    
    DmsDocumentDAObject dmsDocumentDAObject = new DmsDocumentDAObject(this.sessionContainer,this.conn);    
    DmsDocument document = (DmsDocument)dmsDocumentDAObject.getByExtRef(mailMessage.getMessageID(),"A");    
    Integer targetParentID = parentIDStr != null ? new Integer(parentIDStr) : null;
    Integer targetRootID = rootIDStr != null ? new Integer(rootIDStr) : null;    
    if(document == null){
      // real store email to dms
      DmsDocument newDocument = saveMailContent(mailMessage,rootIDStr,parentIDStr);
      saveAttachments(mailMessage, newDocument, rootIDStr,parentIDStr);      
    }else{
      List docDetailList = docRetrievalManager.getDocumentDetailList(document.getID());
      document.setDocumentName(mailMessage.getSubject());
      document.setDocumentDetails(docDetailList);
      document.setParentID(targetParentID);
      document.setRootID(targetRootID);
      DmsDocument destinationDoc = (DmsDocument)dmsDocumentDAObject.getObjectByID(TextUtility.parseIntegerObj(parentIDStr));
      DmsDocument copiedDocument = docOperationManager.copyFolder(document, destinationDoc, targetRootID, DmsOperationConstant.COPY_OPERATION_AS_NEW, DmsOperationConstant.COPY_TOP_VERSION, "A");
      
    }    
    
  } 
  
  
  /**
   * saveEmailListAsCompundDocuments
   * @param request
   * @throws ApplicationException
  */
  public void reAnalysByOriEmailFAttachment(HttpServletRequest request,String charset) throws ApplicationException {
    try{
      
      EmailMessage mailMessage = getCurrentEmailMessage(request);
      // if have new subject name replace the old name
      String mailSubject = request.getParameter("mailSubject"+ mailMessage.getID());
      if (mailSubject != null) {
        mailMessage.setSubject(mailSubject.trim());
      }
      
      EmailReceiver receiver =  EmailReceiverFactory.getEmailReceiverInstanceByServerType(sessionContainer,mailServerType);
      
      String catchFileName = "";      
      EmailAttachmentImpl emailAttachmentImpl = null;
      List attachemntList = mailMessage.getAttachments();
      for(int i = 0 ; i< attachemntList.size();i++){
        EmailAttachmentImpl  tempEmailAttachmentImpl = (EmailAttachmentImpl)attachemntList.get(i);
        if(tempEmailAttachmentImpl.getIsOrigEmail()){
          emailAttachmentImpl = tempEmailAttachmentImpl;
        }
      }
      catchFileName = emailAttachmentImpl.getCatchFileName();
      DataInputStream inputStream ;
      EmailMessageImpl emlEmailMessage = null;
      String cachePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);            
      String trueFilePath = cachePath + catchFileName;
      File file = new File(trueFilePath);
      if (file.exists()) {
        inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(trueFilePath)));
        //get the eml from the attachment,the emlEmailMessage is real emailmessage bean
        Session mailSession = Session.getDefaultInstance(System.getProperties(), null);
        MimeMessage msg = new MimeMessage(mailSession,inputStream);
        receiver.setEmailCharset(charset);
        emlEmailMessage =  receiver.analysemailEmailMessage(msg);
        emlEmailMessage.setID(mailMessage.getID());
        emlEmailMessage.setAnalyzed(true);
        emailAttachmentImpl.setAttachFileName(emlEmailMessage.getSubject()+".eml");
        emlEmailMessage.addAttachment(emailAttachmentImpl);
        receiver.setEmailCharset("");
        inputStream.close();          
      }
      
      inputStream = null;
      file = null;
      
      
      List list = new ArrayList();
      List emailList = (List) request.getSession().getAttribute("sessEmailList");    
      // here is replace the sessEmailList, if saved email will be marked
      for (int i = 0; i < emailList.size(); i++) {
        EmailMessageImpl email = (EmailMessageImpl) emailList.get(i);
        if (mailMessage.getID().intValue()==email.getID().intValue()) {
          list.add(emlEmailMessage);
        }else{
          list.add(email);
        }
      }
      request.getSession(true).setAttribute("sessEmailList", list);     
      
    }catch(Exception e){
      log.error(e, e);
    }
  }    
  
  
}